﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Text.RegularExpressions;
using HtmlAgilityPack;
using Wulong.Phone.Dianping.Constants;
using Wulong.Phone.Dianping.Models;

namespace Wulong.Phone.Dianping.Services
{
    public class PromotionService
    {
        private static readonly string BaseUrl = CommonConstants.MobileHomePage;
        public static IObservable<Promotion> ObservablePromotion(string cityCode, int page, int mode, int mcId, int mrId)
        {
            var format = BaseUrl + "/promolist.aspx?c={0}&mode={1}&pg={2}&mcid={3}&mrid={4}";
            var url = string.Format(format, cityCode, mode, page, mcId, mrId);
            var queryUrl = new Uri(url);//YqlHelper.HtmlQuery(url, "//dl");
            return from request in Observable.Return((HttpWebRequest)WebRequest.Create(queryUrl))
                   from response in Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)()
                   from item in GetPromotionItem(response.GetResponseStream()).ToObservable(Scheduler.ThreadPool)
                   .ObserveOn(Scheduler.ThreadPool)
                   select item;
        }

        private static IEnumerable<Promotion> GetPromotionItem(Stream stream)
        {
            var html = new HtmlDocument();
            html.Load(stream);
            var items = html.DocumentNode.Descendants("dl");
            foreach (var item in items)
            {
                var promo = new Promotion();
                var nameNode = item.Descendants("dt").FirstOrDefault();
                if (nameNode != null)
                {
                    var orDefault = nameNode.Descendants("a").FirstOrDefault();
                    if (orDefault != null)
                    {
                        promo.Link = orDefault.GetAttributeValue("href", "");
                        var idRegex = new Regex(".+\\?c=\\d+&mpid=(\\d+)");
                        promo.Id = idRegex.Match(promo.Link).Groups[1].Value;
                        var imageNode = orDefault.Descendants("img").FirstOrDefault();
                        if(imageNode!=null)
                            promo.ImageUrl = imageNode.GetAttributeValue("src", "");
                    }
                }
                var titleNode = item.Descendants("dd").FirstOrDefault();
                if (titleNode != null)
                    promo.Title = titleNode.InnerText;
                var subtitleNode = item.Descendants("dd").LastOrDefault();
                if (subtitleNode != null)
                    promo.SubTitle = subtitleNode.InnerText;
                yield return promo;
            }
        }

        public static IObservable<Promotion> ObservabelPromotionItem(string cityId, string promoId)
        {
            string detailFormat = BaseUrl + "/promodetail.aspx?c={0}&mpid={1}";
            string url = string.Format(detailFormat, cityId, promoId);
            var queryUrl = new Uri(url);//YqlHelper.HtmlQuery(url, "//div[@class='yhq_detail']");
            return from request in Observable.Return((HttpWebRequest)WebRequest.Create(queryUrl))
                   from response in Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetResponse)()
                   from item in GetPromotionItemDetail(response.GetResponseStream(), promoId).ToObservable(Scheduler.ThreadPool)
                   .ObserveOn(Scheduler.ThreadPool)
                   select item;
        }

        private static IEnumerable<Promotion> GetPromotionItemDetail(Stream stream, string promoId)
        {
            var html = new HtmlDocument();
            html.Load(stream);
            var items = html.DocumentNode.Descendants("div")
                .Where(x=>x.HasAttributes
                    && x.Attributes[0].Value == "yhq_detail");
            foreach (var item in items)
            {
                var promo = new Promotion {Id = promoId};
                var titleNode = item.Descendants("h4").FirstOrDefault();
                if (titleNode != null)
                    promo.Title = titleNode.InnerText;
                var subtitleNode = item.Descendants("h3").FirstOrDefault();
                if (subtitleNode != null)
                    promo.SubTitle = subtitleNode.InnerText;
                var contentNode = item.Descendants("p")
                    .Where(x => x.HasAttributes 
                        && x.Attributes[0].Value == "high_margin").FirstOrDefault();
                if (contentNode != null)
                    promo.Content = contentNode.InnerText;
                var noticeNode = item.Descendants("div")
                    .Where(x => x.HasAttributes 
                        && x.Attributes[0].Value == "color_c")
                        .FirstOrDefault();
                if (noticeNode != null)
                {
                    var notices = noticeNode.Descendants("p");
                    foreach (var notice in notices)
                    {
                        promo.Notice += "\r\n" + notice.InnerText;
                    }
                    promo.Notice = promo.Notice.Trim();
                }
                yield return promo;
            }
           
        }

        public static string SendToMyPhoneLink(string cityCode, string promoId)
        {
            return string.Format(BaseUrl + "/promosend.aspx?c={0}&pid={1}", cityCode, promoId);
        }
    }
}
